import java.awt.Image;
import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.net.URL;

import javax.media.opengl.GL;
import javax.media.opengl.glu.GLU;

import com.sun.opengl.util.texture.Texture;
import com.sun.opengl.util.texture.TextureData;
import com.sun.opengl.util.texture.TextureIO;

public class Map {
	GL gl;
	GLU glu;
	private int shaderprogram, map_texture[];
	private int vert_shader, frag_shader;
	public Vector3D center;
	private float radius;
	Texture boxTexture1;
	
	public Map(GL gl_, GLU glu_){
		gl=gl_;
		glu=glu_;
		map_texture = new int[1];
		center = new Vector3D();
		loadShader();
		CreateTexture(null);
	}
	private void CreateTexture(Image image)
	 {
	 
				URL imageURL= this.getClass().getResource(
						 "map.png");
			        
				 TextureData data=null;
				 try {
					 data = TextureIO.newTextureData(
							 imageURL.openStream(),false, "png");
					 boxTexture1 = TextureIO.newTexture(data);
				 } catch (IOException exc) {
					 exc.printStackTrace();
					 System.exit(1);
				 }       
				 gl.glEnable(GL.GL_TEXTURE_2D);
				 
				 gl.glGenTextures(1,map_texture, 0);
				 gl.glBindTexture(GL.GL_TEXTURE_2D, map_texture[0]);
				 gl.glTexImage2D(GL.GL_TEXTURE_2D, 0,GL.GL_RGBA,data.getWidth(),data.getHeight(),0,GL.GL_RGBA,
						 GL.GL_UNSIGNED_BYTE,data.getBuffer());
			
	}
	
	 private void loadShader(){
		 vert_shader = gl.glCreateShader(GL.GL_VERTEX_SHADER);
	        frag_shader = gl.glCreateShader(GL.GL_FRAGMENT_SHADER);
	        
	        BufferedReader brv = null;
			try {
				brv = new BufferedReader(
						new FileReader(
								"src/map.vert"));
			} catch (FileNotFoundException e1) {
				// TODO Auto-generated catch block
				e1.printStackTrace();
			}
	        String vsrc = "";
	        String line;
	        try {
				while ((line=brv.readLine()) != null) {
				  vsrc += line + "\n";
				}
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
	        gl.glShaderSource(vert_shader, 1,
	        		new String[] {vsrc}, (int[])null, 0);
	        gl.glCompileShader(vert_shader);
	        
	        BufferedReader brf = null;
			try {
				brf = new BufferedReader(
						new FileReader(
								"src/map.frag"));
			} catch (FileNotFoundException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
	        String fsrc = "";
	        String lines;
	        try {
				while ((lines=brf.readLine()) != null) {
				  fsrc += lines + "\n";
				}
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
	        gl.glShaderSource(frag_shader, 1,
	        		new String[] {fsrc}, (int[])null, 0);
	        gl.glCompileShader(frag_shader);
	        
	        shaderprogram = gl.glCreateProgram();
	        gl.glAttachShader(shaderprogram, vert_shader);
	        gl.glAttachShader(shaderprogram, frag_shader);
	        gl.glLinkProgram(shaderprogram);
	        gl.glValidateProgram(shaderprogram);
	 }
	 private void setShader(){
		    
		    gl.glActiveTexture(GL.GL_TEXTURE0);
		    gl.glBindTexture(GL.GL_TEXTURE_2D,map_texture[0]-1);

	        gl.glUniform1i(gl.glGetUniformLocation(
	        		shaderprogram, "tex1"), 0);
	 }
	 public void draw(Camera player,float width, float height,float radius2) {
		 		//System.out.println(flash);
		 		radius = radius2;
		 		float w, h;
		 		w = radius;
		 		h = radius/2.0f;
		 		float yaw = player.yaw;
		 		float pitch = player.pitch;
		 		center.setXYZ(Camera.pos.x,Camera.pos.y,Camera.pos.z);
			    Vector3D point1 = new Vector3D(-2.5f,-w,-h);
			    Vector3D point2 = new Vector3D(-2.5f,w,-h);
			    Vector3D point3 = new Vector3D(-2.5f,w,h);
			    Vector3D point4 = new Vector3D(-2.5f,-w,h);

			    Matrix4x4 maty = new Matrix4x4();
			    Matrix4x4 matz = new Matrix4x4();
			    yaw = -yaw;  
			    pitch = -pitch;
			    maty = Matrix4x4.set((float)Math.cos(pitch),0,(float)Math.sin(pitch),0,
		                   0,1,0,0,
		                   (float)-Math.sin(pitch),0,(float)Math.cos(pitch),0,
		                   0,0,0,1);
		    

			    matz = Matrix4x4.set((float)Math.cos(yaw+Atmosphere.pi),(float)-Math.sin(yaw+Atmosphere.pi),0,0,
		    		(float)Math.sin(yaw+Atmosphere.pi),(float)Math.cos(yaw+Atmosphere.pi),0,0,
		                   0,0,1,0,
		                   0,0,0,1);
			    
			    point1 = Matrix4x4.mult(Matrix4x4.mult(matz,maty),point1);
			    point2 = Matrix4x4.mult(Matrix4x4.mult(matz,maty),point2);
			    point3 = Matrix4x4.mult(Matrix4x4.mult(matz,maty),point3);
			    point4 = Matrix4x4.mult(Matrix4x4.mult(matz,maty),point4);
			    gl.glEnable(GL.GL_ALPHA_TEST);
			    gl.glEnable(GL.GL_BLEND);
			    gl.glBlendFunc(GL.GL_SRC_ALPHA,GL.GL_ONE_MINUS_SRC_ALPHA);
			    gl.glUseProgram(shaderprogram);

			    setShader();

			    gl.glDisable(GL.GL_CULL_FACE);
			    gl.glBegin(GL.GL_QUADS);
			    	gl.glTexCoord2d(0,1);
			    	gl.glVertex3f(point1.x()+center.x(),point1.y()+center.y(),point1.z()+center.z());

			    	gl.glTexCoord2d(1,1);
			    	gl.glVertex3f(point2.x()+center.x(),point2.y()+center.y(),point2.z()+center.z());

			    	gl.glTexCoord2d(1,0);
			    	gl.glVertex3f(point3.x()+center.x(),point3.y()+center.y(),point3.z()+center.z());

			    	gl.glTexCoord2d(0,0);
			    	gl.glVertex3f(point4.x()+center.x(),point4.y()+center.y(),point4.z()+center.z());
			    gl.glEnd();
			    gl.glEnable(GL.GL_CULL_FACE);
			    gl.glUseProgram(0);
			    gl.glDisable(GL.GL_ALPHA_TEST);
			    gl.glDisable(GL.GL_BLEND);
	}
}